package com.bellszhu.elasticsearch.plugin.synonym.analysis;

import com.bellszhu.elasticsearch.plugin.util.JDBCUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.synonym.SynonymMap;
import org.elasticsearch.env.Environment;

import java.io.Reader;
import java.io.StringReader;
import java.sql.Connection;

/**
 * Created by Gary on 2020-05-20.
 *
 * @author Gary
 * @version 3.1.5.M1
 * @since 3.1.5.M1
 */
public class JdbcSynonymFile implements SynonymFile {
    private static Logger logger = LogManager.getLogger("dynamic-synonym");
    private String format;

    private boolean expand;

    private Analyzer analyzer;

    private Environment env;

    /**
     * Remote URL address
     */
    private String location;

    /**
     * jdbc user name
     */
    private String userName;
    /**
     * jdbc password
     */
    private String password;

    private long lastVersion = 0;

    JdbcSynonymFile(Environment env, Analyzer analyzer,
                    boolean expand, String format,
                    String location, String userName, String password) {
        this.analyzer = analyzer;
        this.expand = expand;
        this.format = format;
        this.env = env;
        this.location = location;
        this.userName = userName;
        this.password = password;

        isNeedReloadSynonymMap();
    }

    @Override
    public SynonymMap reloadSynonymMap() {
        try {
            logger.debug("start reload local synonym from jdbc.");
            Reader rulesReader = getReader();
            SynonymMap.Builder parser = RemoteSynonymFile.getSynonymParser(rulesReader, format, expand, analyzer);
            return parser.build();
        } catch (Exception e) {
            logger.error("reload local synonym from jdbc error!", e);
            throw new IllegalArgumentException(
                    "could not reload jdbc synonyms to build synonyms", e);
        }
    }

    @Override
    public boolean isNeedReloadSynonymMap() {
        Connection connection = JDBCUtils.getConnection(location, userName, password);
        logger.debug("start get last version from jdbc.");
        if (connection != null) {
            long maxVersion = JDBCUtils.getLastVersion(connection);
            logger.debug("last version from jdbc is {}.", maxVersion);
            if (lastVersion < maxVersion) {
                lastVersion = maxVersion;
                return true;
            }
        }
        return false;
    }

    @Override
    public Reader getReader() {
        logger.debug("start query synonym from jdbc.");
        Connection connection = JDBCUtils.getConnection(location, userName, password);
        if (connection == null) {
            return new StringReader("");
        }
        return JDBCUtils.querySynonymRules(connection, lastVersion);
    }
}
